package com.zhonglz.commons.interceptor;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.zhonglz.model.SysLog;
import com.zhonglz.service.SysLogService;
import com.zhonglz.util.Constans;
import com.zhonglz.util.base64.Base64Utils;
import com.zhonglz.util.hex.HexUtils;
import com.zhonglz.util.jwt.JwtUtils;
import com.zhonglz.util.sm4.Sm4Utils;
import com.zhonglz.util.tools.IpUtils;
import com.zhonglz.util.tools.ObjectUtils;

/***
 * 系统日志过滤器
 * SysLogInterceptor
 * @author zhonglz
 * @date 2019年11月11日
 */
public class SysLogInterceptor implements HandlerInterceptor {

	private static final Logger logger = LoggerFactory.getLogger(SysLogInterceptor.class);
	
	// 请求开始时间标识
	private static final String LOGGER_START_TIME = "START_TIME";
	// 请求记录器实体标识
	private static final String LOGGER_MODEL = "LOGGER_MODEL";
	
	@Autowired
	private SysLogService sysLogService;
	
	@Override
	public boolean preHandle(HttpServletRequest req, HttpServletResponse httpServletResponse, Object o)
			throws Exception {
		// 获取请求路径
		String url = req.getRequestURI();
		if (isLogger(url)) {
			return true;
		}
		if (url.indexOf("error") > -1) {
			url = (String) req.getAttribute("javax.servlet.error.request_uri");
		}
		if (isLogger(url)) {
			return true;
		}
		
		SysLog sysLog = new SysLog();
		// 获取SESSIONID
		String sessionId = req.getRequestedSessionId();
		// 获取客户端IP
		sysLog.setReqIp(IpUtils.getCliectIp(req));
		// 获取请求方法
		sysLog.setReqMethod(req.getMethod());
		// 获取请求参数
		String reqParam = JSON.toJSONString(req.getParameterMap(), SerializerFeature.DisableCircularReferenceDetect,
				SerializerFeature.WriteMapNullValue);
		
		if(reqParam.length() > 1024) {
			reqParam ="参数太长，不做处理";
		}
		
		// 设置请求参数内容json字符串
		sysLog.setReqParam(reqParam);
		// 设置请求地址
		sysLog.setReqUrl(url);
		
		String id=null;
		String token = req.getHeader("Authorization");//获取请求头中token值
		if(ObjectUtils.isNotEmpty(token)) {
			try {
				JwtUtils.verify(token);
				DecodedJWT userTokenStr =JwtUtils.getTokenInfo(token);
				id = userTokenStr.getClaim("id").asString();//获取添加的数据->进行取出
			} catch (Exception e) {
				logger.debug("记录日志："+e.getMessage());
			}
		}
		// 设置SESSIONID
		sysLog.setSessionId(token);
		sysLog.setUserId(id);
		req.setAttribute(LOGGER_START_TIME, System.currentTimeMillis());
		req.setAttribute(LOGGER_MODEL, sysLog);
		logger.debug(url+"---begin");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest req, HttpServletResponse resp, Object o, Exception e)
			throws Exception {
		String url = req.getRequestURI();
		if (isLogger(url)) {
			return;
		}
		if (url.indexOf("error") > -1) {
			url = (String) req.getAttribute("javax.servlet.error.request_uri");
		}
		if (isLogger(url)) {
			return;
		}
		// 当前时间
		long currentTime = System.currentTimeMillis();
		// 请求开始时间
		long time = Long.valueOf(req.getAttribute(LOGGER_START_TIME).toString());
		// 获取本次请求记录器实体
		SysLog sysLog = (SysLog) req.getAttribute(LOGGER_MODEL);
		// 计算请求消耗时间
		int xhTime=(int)(currentTime - time);
		sysLog.setReqTime(xhTime);
		// 请求时间
		sysLog.setCreateTime(new Date());
		// 响应码
		sysLog.setRespCode(resp.getStatus());
		// 请求详情
		sysLog.setReqDesc(JSON.toJSONString(req.getAttribute(Constans.LOGGER_RETURN),
				SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue));
		// 记录写入数据库
		sysLogService.insertLogger(sysLog);
		
		logger.debug(url+"---end,执行时长为:"+xhTime+"毫秒");
	}

	public boolean isLogger(String url) {
		if (url == null) {
			return true;
		}
		if (url.indexOf("commons") > -1 || url.indexOf("top") > -1 || url.indexOf("left") > -1
				|| url.indexOf("static") > -1 || url.indexOf("right") > -1) {
			return true;
		}
		return false;
	}
}
